热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Impala排查|Impala查询卡顿分析案例

最近在开发时遇到查询卡顿(stuck)的情况,感觉比较有代表性,因此记录一下排查过程。在生产环境中也可以用类似的方法找到卡顿的源头。注:本文所用的Impala版本为3.4.0-SN



最近在开发时遇到查询卡顿(stuck)的情况,感觉比较有代表性,因此记录一下排查过程。
在生产环境中也可以用类似的方法找到卡顿的源头。



注:
本文所用的Impala版本为3.4.0-SNAPSHOT。
Impala由C++和Java写成,分别对应BE (Backend) 和 FE (Frontend) 两部分。


案例描述



使用Alter Table语句新建一个partition时,查询一直不返回。
在Coordinator网页上可以看到查询一直处于CREATED状态,且持续长达十几分钟:





这个查询设置了 sync_ddl=true,在忙碌的集群里是有可能十几分钟未完成的,但在我的测试环境里就不应该这样。


Alter Table Add Partition语句属于DDL,设置sync_ddl=true时,其执行流程如下:





图中各个步骤如下:


(1) 客户端发送查询请求


(2) Coordinator向Catalogd发送ExecDdl请求


(3) Catalogd向HMS发送AddPartition请求


(4) HMS创建Partition,并在HDFS中创建partition目录


(5) Catalogd向NameNode加载新Partition的文件信息



(6) Catalogd在执行完DDL后,将元数据的更新发送给Statestore。
Statestore会将更新广播给所有Coordinator。


(7) Catalogd返回包含更新的topic version给Coordinator


(8) Coordinator等到所有Coordinator都接收到了该version的更新时再返回给客户端


卡顿可能发生在上面任何一步中,需要从头开始排查。


查找卡顿源头


I. 找到Coordinator卡住的线程



查询是发给Coordinator的,因此从它开始。
先查日志,找到这个查询相关的log。
每个查询在被解析的时候都会打一行 “Analyzing ...” 这样的日志,借此找到查询:


$ grep -i analyzing /tmp/impalad_node2.INFO | grep 'ALTER TABLE insert_inherit_permission'
I1101 09:52:17.002415 20747 Frontend.java:1256] a14a8bbbaf75bf19:63c6f76f00000000] Analyzing query: ALTER TABLE insert_inherit_permission ADD PARTITION(p1=1, p2=1, p3=1) db: default


我的查询是 "ALTER TABLE insert_inherit_permission ADD PARTITION(p1=1, p2=1, p3=1)",在grep的时候可以加上些关键字快速定位。
在我的测试环境中,日志是在 /tmp/impalad_node2.INFO,一般在CDH集群中,日志是在 /var/log/impalad/impalad.INFO。



日志中第三列就是线程id,因此FE处理这个查询的线程id是20747。
可以看下这个线程所有的log,看到最后是停在 "Analysis and authorization finished":





既然已经做完语义分析和权限鉴定了,查询是卡在哪里呢?



先通过 jstack 看是否有相关信息,jstack输出中的nid就是十六进制的线程id,在我的例子中并没有发现线程20747的堆栈,因此要查看所有BE的线程了。
BE是C++写的,理论上我们可以通过gdb attach上impalad,然后打出线程堆栈。
但这样会停住整个impalad进程,可能会导致心跳超时而查询被取消的情况。
为了不污染现场环境,可以使用gcore触发一次core dump。


$ gcore
usage: gcore [-o filename] pid
$ sudo gcore -o impalad_core 19731
......
[New LWP 20697]
[New LWP 20747]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Installing openjdk unwinder
Traceback (most recent call last):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 52, in
class Types(object):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 66, in Types
nmethodp_t = gdb.lookup_type('nmethod').pointer()
gdb.error: No type named nmethod.
pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
185 ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: No such file or directory.
warning: target file /proc/19731/cmdline contained unexpected null characters
Saved corefile impalad_core.19731


Dump的时候会被形如 "[New LWP xxxxx]" 的输出刷屏,还可能会有warning,但不用管,只要最后是成功的就行了。
生成的core文件一般会比较大,因为把进程的内存也dump下来了。
比如在我的开发环境中,core文件就有12GB。


$ ll -h impalad_core.19731
-rw-r--r-- 1 root root 12G 11月 1 10:08 impalad_core.19731


生产环境中的内存可能会更大,仍用core dump就不太合适了,后面我们再介绍其它的办法。
有了core文件后,就可以用gdb来分析了。
可能会占用大量内存,因此在生产环境中最好换台机器做分析。


$ gdb -c impalad_core.19731 /home/quanlong/workspace/Impala/be/build/latest/service/impalad
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/quanlong/workspace/Impala/be/build/latest/service/impalad...done.
[New LWP 19731]
[New LWP 19762]
...
[New LWP 20697]
[New LWP 20747]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/home/quanlong/workspace/Impala/be/build/latest/service/impalad'.
#0 pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
185 ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: No such file or directory.
[Current thread is 1 (Thread 0x7f2f3fde48c0 (LWP 19731))]
Installing openjdk unwinder
Traceback (most recent call last):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 52, in
class Types(object):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 66, in Types
nmethodp_t = gdb.lookup_type('nmethod').pointer()
gdb.error: No type named nmethod.
(gdb)

找到线程20747并查看堆栈,gdb里的线程编号并不是线程id,但thread指令只能跳到指定编号的线程,因此我们要先用 "thread find 20747" 找到线程编号,然后再切到那个线程用bt指令打印堆栈:


(gdb) thread find 20747
Thread 285 has target id 'Thread 0x7f2e8f3f2700 (LWP 20747)'
(gdb) thread 285
[Switching to thread 285 (Thread 0x7f2e8f3f2700 (LWP 20747))]
#0 0x00007f2f3f7da87f in __libc_recv (fd=403, buf=0x10e9e000, n=131072, flags=0) at ../sysdeps/unix/sysv/linux/x86_64/recv.c:28
28 ../sysdeps/unix/sysv/linux/x86_64/recv.c: No such file or directory.
(gdb) bt
#0 0x00007f2f3f7da87f in __libc_recv (fd=403, buf=0x10e9e000, n=131072, flags=0) at ../sysdeps/unix/sysv/linux/x86_64/recv.c:28
#1 0x0000000004ccd3af in apache::thrift::transport::TSocket::read(unsigned char*, unsigned int) ()
......

输出的结果会比较长,如图所示:





最重要的是划红线的部分,也就是这块:


#15 0x0000000002513982 in impala::ClientConnection::DoRpc
#16 0x000000000250fb8c in impala::ClientConnection::DoRpcWithRetry
#17 0x000000000250cced in impala::CatalogOpExecutor::Exec
#18 0x00000000022b9012 in impala::ClientRequestState::ExecDdlRequest
#19 0x00000000022b4253 in impala::ClientRequestState::Exec
#20 0x0000000002241cea in impala::ImpalaServer::ExecuteInternal
#21 0x000000000224131d in impala::ImpalaServer::Execute


所以Coordinator是向Catalogd发了RPC请求,正在等待结果返回。
堆栈里有代码行号,也可查看相关代码。


现在可以确认Coordinator是卡在RPC上了,接下来需要确认Catalogd在做什么。


II. 找到Catalogd卡住的线程



Catalogd的日志里并没有发现明显的问题,还是得看线程堆栈。
我这里catalogd比较闲,jstack结果中只有一个是跟ExecDdl相关的:


"Thread-10" #43 prio=5 os_prio=0 tid=0x0000000012324800 nid=0x510c in Object.wait() [0x00007f6808952000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.apache.impala.catalog.CatalogServiceCatalog.waitForSyncDdlVersion(CatalogServiceCatalog.java:2635)
- locked <0x0000000722aff010> (a org.apache.impala.catalog.TopicUpdateLog)
at org.apache.impala.service.CatalogOpExecutor.execDdlRequest(CatalogOpExecutor.java:414)
at org.apache.impala.service.JniCatalog.execDdl(JniCatalog.java:167)

因此源头就是卡在FE的 CatalogServiceCatalog.waitForSyncDdlVersion() 里,线程id是0x510c,也就是20748. 回看日志,最后一行输出是 "Loaded file and block metadata for ..."






因此该表的metadata加载已经完成了,进入waitForSyncDdlVersion是因为该查询使用了sync_ddl=true,catalogd需要等到更新被发送出去才能知道对应的statestore topic version,才能返回给coordinator。
关于metadata的广播及sync_ddl的实现篇幅较长,我们在后续的文章中再介绍。



到此我的诊断就结束了,可以结合代码去debug。
然而在生产环境中catalogd一般很忙碌,不一定能直接锁定jstack中的线程。
有一个想法是通过coordinator线程确定跟catalogd连接的端口,再以此找到catalogd对应的线程,但fd是所有线程共享的,并没法通过端口来找到线程。
因此目前也没有比较好的办法,好在catalogd的大部分逻辑都是java实现的,可以多打几次jstack,对比看哪些线程一直存在来排查。


使用Minidump替代Core Dump



生产环境中的impalad内存一般会比较大,如果使用core dump,生成的core文件也会很大,不利于分析。
实际上我们感兴趣的是各个线程的堆栈,并不需要所有的内存数据。
Google Breakpad 提供的 Minidumps 提供了新的解决方案,它只会导出崩溃原因、各个线程不超过8KB的栈内存、运行环境(OS、CPU等)和进程信息(加载的模块等)。
这样导出的 Minidump 文件就非常小,在本例中,core dump文件的大小是 12GB,minidump 文件的大小却只有 3MB!


使用要求





  • Impala版本不低于2.7

    Impala 2.7(对应的CDH版本是cdh5.9)开始支持外界触发的Minidump,只需要给进程发送SIGUSR1信号。





  • 编译对应版本的Impala源码

    需要使用 Debug 模式编译才能保留所有符号信息(symbol),还需要使用toolchain中的breakpad工具来处理minidump。
    另外编译环境要跟线上环境一致,比如线上环境为ubuntu16.04,编译时也要找ubuntu16.04的机器来做。
    关于如何编译,可参考文档:


    https://cwiki.apache.org/confluence/display/IMPALA/Building+Impala







使用方法






1. 生成Minidump




找到impalad进程的PID,我这里是19731,然后用 "kill -s SIGUSR1 19731" 触发Minidump,成功后在impalad的日志中能找到生成的路径:


Wrote minidump to /tmp/minidumps/impalad/2d32f167-9189-4fdc-9fc4ef9d-624b3a1d.dmp

把这个minidump文件传送到编译Impala的机器上。





2. 生成符号信息



Minidump文件并不包含任何符号信息,因此我们要自己生成Breakpad形式的符号信息来匹配上,这样我们才能看到函数名(而不只是函数地址)等等。


在编译Impala的目录(下称IMPALA_HOME)里,可以找到 bin/dump_breakpad_symbols.py,用它来生成breakpad形式的符号信息,假设说我们希望把符号信息存到 /tmp/syms,指令如下:


$ cd $IMPALA_HOME
$ source bin/impala-config.sh
$ bin/dump_breakpad_symbols.py -f be/build/latest/service/libfesupport.so be/build/latest/service/impalad be/build/latest/util/libloggingsupport.so -d /tmp/syms
INFO:root:Processing binary file: be/build/latest/service/libfesupport.so
INFO:root:Processing binary file: be/build/latest/service/impalad
INFO:root:Processing binary file: be/build/latest/util/libloggingsupport.so

生成的文件大小是421MB,比Minidump文件还大一些,因为里面有各种文件名、函数名等:


$ du -sh /tmp/syms
421M /tmp/syms
$ head /tmp/syms/impalad/0894679AAB4BBE9079BA0C593F2114890/impalad.sym
MODULE Linux x86_64 0894679AAB4BBE9079BA0C593F2114890 impalad
INFO CODE_ID 9A6794084BAB90BE79BA0C593F211489
FILE 0 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/exception.c
FILE 1 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/hdfs.c
FILE 2 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jclasses.c
FILE 3 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c
FILE 4 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/os/posix/mutexes.c
FILE 5 /container.redhat6/build/cdh/hadoop/3.0.0-cdh6.x-SNAPSHOT/rpm/BUILD/hadoop-3.0.0-cdh6.x-SNAPSHOT/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/os/posix/thread_local_storage.c
FILE 6 /home/quanlong/workspace/Impala/be/generated-sources/gen-cpp/BackendGflags_types.cpp
FILE 7 /home/quanlong/workspace/Impala/be/generated-sources/gen-cpp/BackendGflags_types.h


3. 解析Minidump


使用Impala toolchain里的breakpad工具,假设对应的版本是 IMPALA_BREAKPAD_VERSION, 指令如下:


$IMPALA_TOOLCHAIN/breakpad-$IMPALA_BREAKPAD_VERSION/bin/minidump_stackwalk $MINIDUMP_FILE $BREAKPAD_SYMBOLS > $RESULT_FILE

在本例中就是:


$ $IMPALA_HOME/toolchain/breakpad-97a98836768f8f0154f8f86e5e14c2bb7e74132e-p2/bin/minidump_stackwalk /tmp/minidumps/impalad/2d32f167-9189-4fdc-9fc4ef9d-624b3a1d.dmp /tmp/syms > /tmp/resolved.txt
......
2019-11-03 08:33:22: basic_code_modules.cc:110: INFO: No module at 0x0
2019-11-03 08:33:22: basic_code_modules.cc:110: INFO: No module at 0x0
2019-11-03 08:33:22: minidump_processor.cc:326: INFO: Processed /tmp/minidumps/impalad/2d32f167-9189-4fdc-9fc4ef9d-624b3a1d.dmp
2019-11-03 08:33:22: minidump.cc:4980: INFO: Minidump closing minidump

中间会有刷屏的输出,只要最终解析成功就行了。生成的文件内容如下:


Operating system: Linux
0.0.0 Linux 4.15.0-66-generic #75~16.04.1-Ubuntu SMP Tue Oct 1 14:01:08 UTC 2019 x86_64
CPU: amd64
family 6 model 158 stepping 10
1 CPU

GPU: UNKNOWN

Crash reason: DUMP_REQUESTED
Crash address: 0x4d78597
Process uptime: not available

Thread 0 (crashed)
0 impalad!google_breakpad::ExceptionHandler::WriteMinidump() + 0x57
rax = 0x00007ffeed518510 rdx = 0x0000000000000000
rcx = 0x0000000004d7857f rbx = 0x0000000000000000
rsi = 0x0000000000000001 rdi = 0x00007ffeed5183a8
rbp = 0x00007ffeed518ab0 rsp = 0x00007ffeed518310
r8 = 0x0000000000000000 r9 = 0x0000000000000024
r10 = 0x00007f2f3f7db340 r11 = 0x00007ffeed518980
r12 = 0x00007ffeed518970 r13 = 0x0000000002428f99
r14 = 0x0000000000000000 r15 = 0x00007ffeed5189d0
rip = 0x0000000004d78597
Found by: given as instruction pointer in context
1 impalad!google_breakpad::ExceptionHandler::WriteMinidump(std::string const&, bool (*)(google_breakpad::MinidumpDescriptor const&, void*, bool), void*) + 0xf0
rbx = 0x00007f2f3caf0140 rbp = 0x00007ffeed518ab0
rsp = 0x00007ffeed518960 r12 = 0x00007ffeed518970
r13 = 0x0000000002428f99 r14 = 0x0000000000000000
r15 = 0x00007ffeed5189d0 rip = 0x0000000004d78e60
Found by: call frame info
2 impalad!impala::HandleSignal [minidump.cc : 103 + 0x1e]
rbx = 0x0000000000000000 rbp = 0x00007ffeed518af0
rsp = 0x00007ffeed518ac0 r12 = 0x00007ffeed519250
r13 = 0x00000000111263d0 r14 = 0x0000000000006d62
r15 = 0x0000000000000000 rip = 0x00000000024290ec
Found by: call frame info
3 libpthread-2.23.so + 0x11390
rbx = 0x0000000000000000 rbp = 0x00007ffeed519240
rsp = 0x00007ffeed518b00 r12 = 0x00007ffeed519250
r13 = 0x00000000111263d0 r14 = 0x0000000000006d62
r15 = 0x0000000000000000 rip = 0x00007f2f3f7db390
Found by: call frame info
4 impalad!boost::thread::join_noexcept() + 0x5c
rbp = 0x00007ffeed519260 rsp = 0x00007ffeed519250
rip = 0x0000000003c6a13c
Found by: previous frame's frame pointer
...


先是OS、CPU等环境信息,然后就是各个线程的堆栈信息,每个堆栈的各个寄存器值也都显示出来了。
第一个线程是breakpad做minidump的线程,因为Crash reason是DUMP_REQUESTED(实际上进程还活着,并没有crash)。
如果是在线上环境进程崩溃,则第一个线程会是导致崩溃的线程。


回到Coordinator卡顿的分析,我们先是从日志找到了线程id为20747:


I1101 09:52:17.002415 20747 Frontend.java:1256] a14a8bbbaf75bf19:63c6f76f00000000] Analyzing query: ALTER TABLE insert_inherit_permission ADD PARTITION(p1=1, p2=1, p3=1) db: default


可惜breakpad并没有打出像gdb一样的LWP信息,线程的编号也跟gdb的不一样。
但据观察,线程id(即LWP id)一般会出现在线程堆栈里前几个调用的寄存器里,经常可以借此找到线程。
比如我们关心的线程id是20747,转换成16进制就是510b,在输出文件 /tmp/resolved.txt 里搜510b,刚好只有一个线程其堆栈里前几个调用的寄存器rbx值为 0x000000000000510b,而这个线程的堆栈也正就是 ExecDdl 的堆栈:


Thread 283
...
13 impalad!impala::CatalogServiceClient::recv_ExecDdl(impala::TDdlExecResponse&) [CatalogService.cpp : 1908 + 0x1f]
rbx = 0x0000000000000000 rbp = 0x00007f2e8f3ecf20
rsp = 0x00007f2e8f3ece60 r12 = 0x0000000000000000
r13 = 0x00000000110d1ba8 r14 = 0x0000000002512a7c
r15 = 0x0000000000000000 rip = 0x0000000001c319a4
Found by: call frame info
14 impalad!impala::CatalogServiceClientWrapper::ExecDdl(impala::TDdlExecResponse&, impala::TDdlExecRequest const&, bool*) [catalog-service-client-wrapper.h : 47 + 0x13]
rbx = 0x0000000000000000 rbp = 0x00007f2e8f3ecf90
rsp = 0x00007f2e8f3ecf30 r12 = 0x0000000000000000
r13 = 0x00000000110d1ba8 r14 = 0x0000000002512a7c
r15 = 0x0000000000000000 rip = 0x0000000002512b51
Found by: call frame info
15 impalad!impala::Status impala::ClientConnection::DoRpc(void (impala::CatalogServiceClientWrapper::* const&)(impala::TDdlExecResponse&, impala::TDdlExecRequest const&, bool*), impala::TDdlExecRequest const&, impala::TDdlExecResponse*) [client-cache.h : 243 + 0x31]
rbx = 0x0000000000000000 rbp = 0x00007f2e8f3ed070
rsp = 0x00007f2e8f3ecfa0 r12 = 0x0000000000000000
r13 = 0x00000000110d1ba8 r14 = 0x0000000002512a7c
r15 = 0x0000000000000000 rip = 0x0000000002513982
Found by: call frame info
...
31 impalad!boost::_bi::bind_t, impala::Promise*>, boost::_bi::list3, boost::_bi::value >, boost::_bi::value*> > >::operator()() [bind_template.hpp : 20 + 0x22]
rbx = 0x000000000000510b rbp = 0x00007f2e8f3f18a0
rsp = 0x00007f2e8f3f1860 r12 = 0x0000000000000000
r13 = 0x00007f2e903f9c60 r14 = 0x000000000c7b95c8
r15 = 0x000000000c2822b0 rip = 0x0000000001fe8aa9
Found by: call frame info
32 impalad!boost::detail::function::void_function_obj_invoker0, impala::Promise*>, boost::_bi::list3, boost::_bi::value >, boost::_bi::value*> > >, void>::invoke(boost::detail::function::function_buffer&) [function_template.hpp : 153 + 0xc]
rbx = 0x000000000000510b rbp = 0x00007f2e8f3f18d0
rsp = 0x00007f2e8f3f18b0 r12 = 0x0000000000000000
r13 = 0x00007f2e903f9c60 r14 = 0x000000000c7b95c8
r15 = 0x000000000c2822b0 rip = 0x0000000001fe89bc
Found by: call frame info
33 impalad!boost::function0::operator()() const [function_template.hpp : 767 + 0x11]
rbx = 0x000000000000510b rbp = 0x00007f2e8f3f1910
rsp = 0x00007f2e8f3f18e0 r12 = 0x0000000000000000
r13 = 0x00007f2e903f9c60 r14 = 0x000000000c7b95c8
r15 = 0x000000000c2822b0 rip = 0x0000000001f04e58
Found by: call frame info
34 impalad!impala::Thread::SuperviseThread(std::string const&, std::string const&, boost::function, impala::ThreadDebugInfo const*, impala::Promise*) [thread.cc : 360 + 0xf]
rbx = 0x000000000000510b rbp = 0x00007f2e8f3f1c70
rsp = 0x00007f2e8f3f1920 r12 = 0x0000000000000000
r13 = 0x00007f2e903f9c60 r14 = 0x000000000c7b95c8
r15 = 0x000000000c2822b0 rip = 0x000000000247bf47
Found by: call frame info
...

堆栈里同时也有代码的行号,感兴趣的朋友可以下载整个 resolved.txt 文件 (压缩后73KB) 研究研究:


https://github.com/stiga-huang/BlogFiles/blob/master/Debugging%20on%20Stuck%20Query/resolved.txt.gz


在这之后就知道Coordinator是卡在等待ExecDdl的RPC返回了,后面同样可以对catalogd做分析。



总结



Impalad查询卡顿时,如果日志中无法发现异常,对于BE部分可以使用core dump或minidump来做线程堆栈分析,对于FE部分可以用jstack做分析。
日志中的线程id对应gdb中的 LWP id 和 jstack 中的 nid (16进制),在minidump中找不到明显对应,可试图在寄存器值中匹配线程。



(注:
BE是指Backend,主要是Impala的C++部分;
FE是指Frontend,主要是Impala的Java部分)



指令回顾




  • gcore [-o filename] pid




  • gdb -c core_file program_binary




  • gdb指令





    • thread find thread_id (查找对应线程id在gdb中的线程编号)




    • thread id (跳到对应编号的线程)




    • bt (打印堆栈)





  • jstack pid




  • kill -s SIGUSR1 pid (触发impala进程生成minidump)




  • $IMPALA_HOME/bin/dump_breakpad_symbols.py -f binaries -d output_symbol_dir (生成Breakpad形式的符号文件)





  • $IMPALA_TOOLCHAIN/breakpad-$IMPALA_BREAKPAD_VERSION/bin/minidump_stackwalk $MINIDUMP_FILE $BREAKPAD_SYMBOLS > $RESULT_FILE (解析Minidump






参考文档




  • https://cwiki.apache.org/confluence/display/IMPALA/Debugging+Impala+Core+Dumps+on+Another+System




  • https://cwiki.apache.org/confluence/display/IMPALA/Debugging+Impala+Minidumps




  • https://cwiki.apache.org/confluence/display/IMPALA/Building+Impala




作者简介:黄权隆,Cloudera研发工程师,Apache Impala PMC & Comitter,毕业于北大计算机系网络所数据库实验室,曾就职于Hulu大数据基础架构团队,负责大数据系统的维护和二次开发,主要负责Impala和HBase方向。现就职于Cloudera,专注于Impala开发。





推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
  • JavaScript简介及语言特点
    本文介绍了JavaScript的起源和发展历程,以及其在前端验证和服务器端开发中的应用。同时,还介绍了ECMAScript标准、DOM对象和BOM对象的作用及特点。最后,对JavaScript作为解释型语言和编译型语言的区别进行了说明。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  •     这里使用自己编译的hadoop-2.7.0版本部署在windows上,记得几年前,部署hadoop需要借助于cygwin,还需要开启ssh服务,最近发现,原来不需要借助cy ... [详细]
  • 进入配置文件目录:[rootlinuxidcresin-4.0.]#cdusrlocalresinconf查看都有哪些配置文件:[rootlinuxid ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了解决全栈跨域问题的方法及步骤,包括添加权限、设置Access-Control-Allow-Origin、白名单等。通过这些操作,可以实现在不同服务器上的数据访问,并解决后台报错问题。同时,还提供了解决second页面访问数据的方法。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
author-avatar
王诗昀彦廷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有